package org.invigorare.auctions.data;

import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;

/**
 * Abstract superclass for *DataOpeners that need to periodically download/receive updated data.
 *
 * The difference between inbound and outbound databases is:
 * 	 - outbound databases only need to track whether each entry has been uploaded.
 *   - inbound databases need to track when each entry was received (to limit uploads)
 *   	Note: when synchronizing inbound data from an external data source, the client will need to 
 *				provided a consistent time frame reference,
 *   			e.g. use the time reported by the server.
 * @author jchern
 */

public abstract class SynchronizableInboundDataOpener extends SynchronizableDataOpener {

	protected static final String _LAST_INBOUND_SYNC = "_last_inbound_sync";
	protected static final String _LAST_INBOUND_SYNC_TYPE = SqlTypes.INT; // UNIX Types
	
	private final String tableName, tableNullColName;
	private static final String[] updateTimeCol = new String[] {_LAST_INBOUND_SYNC };
	
	public SynchronizableInboundDataOpener(Context context, String tableName, CursorFactory factory, int version, String nullColName) {
		super(context, tableName, factory, version);
		this.tableName = tableName;
		this.tableNullColName = nullColName;
	}

	/**
	 * Generates the CREATE TABLE string with the specified column names and types,
	 * automatically appending the _LAST_INBOUND_SYNC column.
	 */
	@Override
	protected String createTableString(String tableName, ColBinding[] columns) {
		ColBinding[] appendedCols = appendColumnDef(columns, new ColBinding(_LAST_INBOUND_SYNC, _LAST_INBOUND_SYNC_TYPE));
		return super.createTableString(tableName, appendedCols);
	}
	
	/**
	 * Returns the oldest (smallest valued) update time of any entry in this db.
	 * This time value is the one we report to the web server when requesting an update.
	 * @return
	 */
	@Deprecated
	public long getOldestUpdateTime() {
		SQLiteDatabase db = this.getReadableDatabase();
		
		String selection = null; // select all
		String groupBy = _LAST_INBOUND_SYNC;
		String having = null;
		String orderBy = "1 ASC"; // the first and only column: containing the timestamp, ascending (lowest first).
		Cursor query = db.query(tableName, updateTimeCol, selection, null, groupBy, having, orderBy);
		
		long result;
		if (query.moveToFirst()) {
			result = query.getLong(0); // get the min timestamp (already sorted)
		} else {
			result = 0; // default initial time
		}
		
		query.close();
		db.close();
		
		return result;
	}
	
	public void addNewRows(List<ContentValues> rows, long reportedServertime) {
		
		SQLiteDatabase db = this.getWritableDatabase();
		for (ContentValues row : rows) {
			row.put(_LAST_INBOUND_SYNC, reportedServertime);
			db.insert(tableName, tableNullColName, row);
		}
		
		Log.i("SYNC INBOUND DB", "server time: " + reportedServertime);
		
		db.close();
	}
}
